package utils

import (
	"bytes"
	"crypto/md5"
	"crypto/sha1"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"image"
	"image/png"
	"io"
	"math"
	"math/rand"
	"net/http"
	"os"
	"reflect"
	"time"
)

const allChar1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const allChar2 = "0123456789"

var Randier = rand.New(rand.NewSource(time.Now().UnixNano()))

func RandChar(t int, size int) string {
	var char = allChar1
	switch t {
	case 2:
		char = allChar2
	}
	//fmt.Println(time.Now().UnixNano())
	//rand.NewSource(time.Now().UnixNano()) // 产生随机种子
	var s bytes.Buffer
	for i := 0; i < size; i++ {
		s.WriteByte(char[Randier.Intn(len(char))])
	}
	return s.String()
}

// RandInt 生成一个指定范围的随机数
func RandInt(min int, max int) int {

	// 生成80到360之间的随机数
	randomNumber := rand.Intn(max - min)

	return randomNumber
}
func Sha1(s string) string {
	h := sha1.New()
	h.Write([]byte(s))
	bs := h.Sum(nil)
	return hex.EncodeToString(bs)
}
func EncodeMD5(s string) string {
	h := md5.New()
	h.Write([]byte(s))
	bs := h.Sum(nil)
	return hex.EncodeToString(bs)
}

func GetUserPreSetPrefix(s string) string {
	return "UserPreSet_" + s
}

func GenCtx(questionCtx, text string) string {
	return fmt.Sprintf("%s(You:%s)", questionCtx, text)
}

func GenPreSet(preset string) string {
	return fmt.Sprintf("(You:%s)OK", preset)
}

func CopyStruct(src interface{}, dest interface{}) error {
	srcValue := reflect.ValueOf(src)
	destValue := reflect.ValueOf(dest).Elem()

	if srcValue.Kind() == reflect.Ptr {
		srcValue = srcValue.Elem()
	}

	if destValue.Kind() == reflect.Ptr {
		destValue = destValue.Elem()
	}
	//
	//if srcValue.Type() != destValue.Type() {
	//	return fmt.Errorf("source and destination types don't match")
	//}

	for i := 0; i < srcValue.NumField(); i++ {
		srcField := srcValue.Field(i)
		destField := destValue.Field(i)

		if srcField.Kind() == reflect.Ptr && srcField.IsNil() {
			continue
		}

		if srcField.Type() == destField.Type() {
			srcFieldValue := reflect.ValueOf(srcField.Interface())
			destField.Set(srcFieldValue)
		} else if srcField.Kind() == reflect.Interface && !srcField.IsNil() {
			srcFieldValue := reflect.ValueOf(srcField.Elem().Interface())
			destField.Set(srcFieldValue)
		} else {
			return fmt.Errorf("field type mismatch: %s", srcValue.Type().Field(i).Name)
		}
	}

	return nil
}

func MkRotateImg(angle float64) string {
	// 随机一个 80 到360 小数
	// 打开图片文件
	file, err := os.Open("./statics/captchaImage/0b003516e950465923e2f0901acc5d9b.png")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	fmt.Println(file)
	// 解码图片
	img, err := png.Decode(file)
	if err != nil {
		fmt.Println(err)
		panic(err)
	}

	// 创建一个新的画布，大小为旋转后的尺寸
	//rotateImg := image.NewRGBA(image.Rect(0, 0, img.Bounds().Dy(), img.Bounds().Dx()))
	//for x := img.Bounds().Min.Y; x < img.Bounds().Max.Y; x++ {
	//	for y := img.Bounds().Max.X - 1; y >= img.Bounds().Min.X; y-- {
	//		rotateImg.Set(img.Bounds().Max.Y-x, y, img.At(y, x))
	//	}
	//}

	// 旋转操作
	//draw.Draw(rotateImg, rotateImg.Bounds(), img, img.Bounds().Min, 180)
	rotateImg := rotatePNG(img, angle)

	// 创建一个内存缓冲区
	buffer := new(bytes.Buffer)
	// 将图片编码为PNG并写入缓冲区
	err = png.Encode(buffer, rotateImg)
	if err != nil {
		panic(err)
	}

	// 将缓冲区的内容转换为Base64编码
	encoded := base64.StdEncoding.EncodeToString(buffer.Bytes())

	return encoded
	// 创建输出文件
	//output, err := os.Create("./statics/tmpImg/" + RandChar(1, 10) + ".png")
	//if err != nil {
	//	panic(err)
	//}
	//defer output.Close()
	//
	//// 保存为JPEG格式图片
	//png.Encode(output, rotateImg)
}

// 生成图片
func rotatePNG(img image.Image, angle float64) *image.RGBA64 {
	// 计算旋转中心
	centerX := img.Bounds().Max.X / 2
	centerY := img.Bounds().Max.Y / 2
	radians := angle * math.Pi / 180.0
	// 创建旋转矩阵
	rotMatrix := image.NewRGBA64(image.Rect(0, 0, img.Bounds().Max.X, img.Bounds().Max.Y))
	for x := 0; x < img.Bounds().Max.X; x++ {
		for y := 0; y < img.Bounds().Max.Y; y++ {
			// 计算原点到当前像素的距离
			dx := x - centerX
			dy := y - centerY

			// 计算旋转后的坐标
			nx := int(math.Cos(radians)*float64(dx)-math.Sin(radians)*float64(dy)) + centerX
			ny := int(math.Cos(radians)*float64(dy)+math.Sin(radians)*float64(dx)) + centerY

			// 将旋转后的像素赋值给旋转矩阵
			rotMatrix.Set(x, y, img.At(nx, ny))
		}
	}

	// 创建新的图片并将旋转矩阵填充进去
	newImg := image.NewRGBA64(rotMatrix.Bounds())
	for x := 0; x < rotMatrix.Bounds().Max.X; x++ {
		for y := 0; y < rotMatrix.Bounds().Max.Y; y++ {
			newImg.Set(x, y, rotMatrix.At(x, y))
		}
	}

	return newImg
}
func HttpImgToBase64(url string) (string, error) {
	// 发起HTTP GET请求，获取图片内容
	response, err := http.Get(url)
	if err != nil {
		fmt.Println("无法获取图片:", err)
		return "", err
	}
	defer response.Body.Close()

	// 读取响应体的内容
	imageData, err := io.ReadAll(response.Body)
	if err != nil {
		fmt.Println("无法读取图片内容:", err)
		return "", err
	}

	// 将图片内容转换为Base64编码
	return base64.StdEncoding.EncodeToString(imageData), nil

}
